#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
KOOK-Ticket-Bot  完整版
仅依赖：khl.py
"""
import asyncio
import json
import logging
import os
from khl import Bot, Event, EventTypes, ChannelTypes, MessageTypes, api

logging.basicConfig(level=logging.INFO, format='[%(asctime)s] %(levelname)s %(name)s: %(message)s')
log = logging.getLogger('TicketBot')

# ---------- 配置 ----------
CFG = json.load(open(os.path.join(os.path.dirname(__file__), 'config.json'), 'r', encoding='utf-8'))

# ---------- 内存 ----------
user_open_tickets = {}      # user_id -> channel_id
ticket_creator = {}         # channel_id -> user_id

# ---------- 工具 ----------
async def try_delete_msg(msg_id: str, delay: int = 5):
    await asyncio.sleep(delay)
    try:
        await bot.client.gate.exec_req(api.Message.delete(msg_id=msg_id))
    except Exception as e:
        log.warning(f'删除消息失败: {e}')

def build_panel_card():
    return [{"type": "card", "size": "lg", "modules": [
        {"type": "header", "text": {"type": "plain-text", "content": "📩  创建 Ticket"}},
        {"type": "section", "text": {"type": "kmarkdown", "content": "点击下方按钮即可建立与客服的私密频道"}},
        {"type": "action-group", "elements": [
            {"type": "button", "text": {"type": "plain-text", "content": "创建 Ticket"}, "value": "create_ticket", "click": "return-val"}
        ]}
    ]}]

def build_welcome_card(user_id: str):
    return [{"type": "card", "size": "lg", "modules": [
        {"type": "section", "text": {"type": "kmarkdown", "content": f"<@{user_id}> {CFG['welcome_text']}"}},
        {"type": "divider"},
        {"type": "section", "text": {"type": "kmarkdown", "content": "Support will be with you shortly.\nTo close this ticket react with 🔒"}},
        {"type": "action-group", "elements": [
            {"type": "button", "text": {"type": "plain-text", "content": "🔒 关闭 Ticket"}, "value": "close_ticket", "click": "return-val"}
        ]}
    ]}]

# ---------- 启动入口 ----------
if __name__ == '__main__':
    bot = Bot(token=CFG['bot_token'])

    # ---------- 事件注册 ----------
    @bot.on_startup
    async def init_panel(bot: Bot):
        try:
            await bot.client.gate.exec_req(
                api.Message.create(
                    channel_id=CFG['panel_channel_id'],
                    content=json.dumps(build_panel_card(), ensure_ascii=False),
                    type=MessageTypes.CARD
                )
            )
            log.info('面板消息已发送')
        except Exception as e:
            log.error(f'面板消息失败: {e}')

    @bot.on_event(EventTypes.MESSAGE_BTN_CLICK)
    async def btn_click(_, evt: Event):
        user_id   = evt.body['user_id']
        channel_id= evt.body['target_id']
        value     = evt.body['value']
        if value == 'create_ticket':
            await handle_create_ticket(user_id, channel_id)
        elif value == 'close_ticket':
            await handle_close_ticket(user_id, channel_id)

    # ---------- 业务函数 ----------
    async def handle_create_ticket(user_id: str, panel_ch: str):
        if user_id in user_open_tickets:
            tip = await bot.client.gate.exec_req(
                api.Message.create(channel_id=panel_ch, content='Ticket limit reached, You already have 1 ticket open.',
                                 type=MessageTypes.KMD, temp_target_id=user_id)
            )
            asyncio.create_task(try_delete_msg(tip['msg_id'], 5))
            return

        user = await bot.client.fetch_user(user_id)
        name = f'{user.username}-{user.identify_num}-ticket'
        try:
            new_ch = await bot.client.gate.exec_req(
                api.Channel.create(
                    name=name,
                    parent_id=CFG['parent_category_id'],
                    type=ChannelTypes.TEXT,
                    private=True,
                    visible_permission=[
                        {'role': CFG['support_role_id'], 'allow': 1},
                        {'role': CFG['user_role_id'],   'deny':  1},
                        {'user': user_id,              'allow': 1}
                    ]
                )
            )
        except Exception as e:
            log.error(f'创建频道失败: {e}')
            tip = await bot.client.gate.exec_req(
                api.Message.create(channel_id=panel_ch, content='创建失败，请联系管理员检查分组权限。',
                                 type=MessageTypes.KMD, temp_target_id=user_id)
            )
            asyncio.create_task(try_delete_msg(tip['msg_id'], 5))
            return

        ch_id = new_ch['id']
        user_open_tickets[user_id] = ch_id
        ticket_creator[ch_id] = user_id

        # 欢迎卡片
        await bot.client.gate.exec_req(
            api.Message.create(
                channel_id=ch_id,
                content=json.dumps(build_welcome_card(user_id), ensure_ascii=False),
                type=MessageTypes.CARD
            )
        )
        # 成功提示
        ok = await bot.client.gate.exec_req(
            api.Message.create(channel_id=panel_ch, content='✅ Ticket 创建成功！',
                             type=MessageTypes.KMD, temp_target_id=user_id)
        )
        asyncio.create_task(try_delete_msg(ok['msg_id'], 5))

    async def handle_close_ticket(user_id: str, ch_id: str):
        if ticket_creator.get(ch_id) != user_id:
            await bot.client.gate.exec_req(
                api.Message.create(channel_id=ch_id, content='❌ 只有 Ticket 主人可以关闭。')
            )
            return
        await bot.client.gate.exec_req(
            api.Message.create(channel_id=ch_id, content='频道将在 3 秒后删除...')
        )
        await asyncio.sleep(3)
        await bot.client.gate.exec_req(api.Channel.delete(channel_id=ch_id))
        user_open_tickets.pop(user_id, None)
        ticket_creator.pop(ch_id, None)

    # ---------- 启动 ----------
    log.info('Ticket-Bot 启动中...')
    bot.run()